trait ISubject<'a> {
    fn register_observer(&mut self, t :&'a dyn IObserver);

    fn remove_observer(&mut self, s: usize) ;

    fn notify(&self, msg :&'a str);

    fn recive_msg(&self, msg :&'a str) {
        self.notify(msg);
    }
}

struct ConcreteSubject<'a> {
    list:Vec<&'a dyn IObserver>
}


impl <'a> ISubject<'a> for ConcreteSubject<'a> {
    fn register_observer(&mut self, t :&'a dyn IObserver) {
        self.list.push(t);
    }

    fn remove_observer(&mut self, s: usize) {
        self.list.remove(s);
    }

    fn notify(&self, msg :&'a str) {
        for _i in &self.list {
            _i.update(msg);
        }
    }
}

trait IObserver {
    fn update<'a>(&self, msg :&'a str);
}

struct ConcreteObserver<'a>{
    name :&'a str
}

impl <'a> IObserver for ConcreteObserver<'a> {
    fn update(&self, msg :&str) {
        println!("{} 接收到了参数 {} 我要去吃饭", self.name, msg);
    }
}

struct ConcreteObserver1<'a>{
    name :&'a str
}

impl <'a> IObserver for ConcreteObserver1<'a> {
    fn update(&self, msg :&str) {
        println!("{} 接收到了参数 {} 我要去上学", self.name, msg);
    }
}


pub fn main() {
    // 首先创建两个观察者，z3 和 l4， 其实，ConcreteObserver应该用不同的IObserver实现，代表不同的观察者接收到了
    // 相同的消息做了不同的动作，
    let z3 = ConcreteObserver{name : "张三"};
    let l4 = ConcreteObserver1{name : "李四"};

    // 创建一个主题，还有一种方式，把主题的引用给观察者，创建观察者的时候，自动注册到主题，共方式暂不实现
    let mut subject = ConcreteSubject{list :Vec::<&dyn IObserver>::new()};

    // 主题绑定观察者
    subject.register_observer(&z3);
    subject.register_observer(&l4);

    // 主题接收到消息，也可以理解为，被观察者产生了变化，主题接收变化
    subject.recive_msg("i'm god")
}
